package com.leadingsoft.controller.browser.impl;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import org.apache.commons.configuration.Configuration;
import org.beetl.sql.core.ClasspathLoader;
import org.beetl.sql.core.ConnectionSource;
import org.beetl.sql.core.ConnectionSourceHelper;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.SQLLoader;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.UnderlinedNameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.ext.DebugInterceptor;
import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.handler.CefLoadHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.leadingsoft.common.CheckUrl;
import com.leadingsoft.common.Constant;
import com.leadingsoft.common.TaskQuene;
import com.leadingsoft.controller.browser.BrowserInstance;
import com.leadingsoft.controller.download.DownloadCtripHotel;
import com.leadingsoft.controller.parse.ParsingCtripHotel;
import com.leadingsoft.core.CommonConfig;
import com.leadingsoft.ui.BrowserFrame;

/**
 * @ClassName UrlBrowserInstance
 * @Description Url浏览器实例<br>
 *              进行数据抓取<br>
 *              下一页是通过修改浏览器地址进行获取<br>
 *              示例网站：携程酒店信息
 * @author gongym
 * @date 2018年6月7日 下午5:09:30
 */
public class CtripHotelBrowserInstance implements BrowserInstance {
	private static Logger logger = LoggerFactory.getLogger(CtripHotelBrowserInstance.class);
	private CefClient nowClient;
	private Boolean nowOsrEnabled;
	private Boolean nowTransparentPaintingEnabled;
	private Configuration config;

	public CtripHotelBrowserInstance(CefClient client, boolean osrEnabled, boolean transparentPaintingEnabled) {
		this.nowClient = client;
		this.nowOsrEnabled = osrEnabled;
		this.nowTransparentPaintingEnabled = transparentPaintingEnabled;
		this.config = CommonConfig.getInstance();
	}
	/**
	 * @Title createBrowserAndCrawler
	 * @Description 创建浏览器实例
	 * @param startIndex
	 * @param stopIndex
	 * @return void
	 */
	@Override
	public void createBrowserAndCrawler(Long startIndex, Long stopIndex) {
		// 给一个起始页创建浏览器对象
		CefBrowser browser = nowClient.createBrowser(Constant.DEFAULTURL, nowOsrEnabled, nowTransparentPaintingEnabled);
		// 数据库连接对象
		String datasourceDriver = config.getString("datasource.driver");
		String datasourceUrl = config.getString("datasource.url");
		String datasourceUsername = config.getString("datasource.username");
		String datasourcePassword = config.getString("datasource.password");
		ConnectionSource source = ConnectionSourceHelper.getSimple(datasourceDriver, datasourceUrl, datasourceUsername,
				datasourcePassword);
		DBStyle mysql = new MySqlStyle();
		SQLLoader loader = new ClasspathLoader("/");
		UnderlinedNameConversion nc = new UnderlinedNameConversion();
		SQLManager sqlManager = new SQLManager(mysql, loader, source, nc, new Interceptor[] { new DebugInterceptor() });
		Integer isDownload = config.getInt("is_download");
		// 添加监听对象
		nowClient.addLoadHandler(new CefLoadHandlerAdapter() {
			@Override
			public void onLoadEnd(CefBrowser browser, CefFrame frame, int what) {
				if (frame.isFocused() && frame.isMain()) {
					String url = browser.getURL();
					logger.debug("应该是页面已经加载完毕了：{}", url);
					if (CheckUrl.isCtripUrl(url)) {
						if (isDownload.equals(1)) {
							logger.debug("需要下载当前页面到指定目录");
							DownloadCtripHotel htmlSource = new DownloadCtripHotel(browser, startIndex, stopIndex);
							browser.getSource(htmlSource);
						} else {
							logger.debug("需要解析当前页面并且保存数据库");
							String listSelector = "hotel_new_list";
							ParsingCtripHotel parsingCtripHotel = new ParsingCtripHotel(browser, listSelector,
									sqlManager, startIndex, stopIndex);
							browser.getSource(parsingCtripHotel);
						}
					} else {
						String startUrl = TaskQuene.getCtripHotelListUrl(null, startIndex, stopIndex);
						TaskQuene.ctripTaskUrl.add(startUrl);
						logger.debug("任务开始访问起始URL：{}", startUrl);
					}
				}
			}
		});
		final BrowserFrame frame = new BrowserFrame(nowClient, browser);
		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				frame.dispose();
				CefApp.getInstance().dispose();
			}
		});
		frame.setSize(1000, 500);
		frame.setVisible(true);
		// 开始抓取数据
		crawlerData(browser);
	}
	/**
	 * @Title: crawlerData
	 * @Description: 循环列表抓取数据
	 * @param browser
	 * @return: void
	 */
	private void crawlerData(CefBrowser browser) {
		while (true) {// 循环调用，如果队列中有任务就会加载页面
			String ctripHotelListUrl = TaskQuene.ctripTaskUrl.poll();
			if (null != ctripHotelListUrl) {
				logger.debug("===================={}任务开始====================", ctripHotelListUrl);
				logger.debug("获取到一个任务URL：{}，开始加载页面", ctripHotelListUrl);
				// 加载页面
				browser.loadURL(ctripHotelListUrl);
			}
		}
	}
}
